package com.example.service.impl;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.dto.ApiResponse;
import com.example.dto.ExamRequest;
import com.example.dto.ExamStatisticsDTO;
import com.example.dto.MarkingSubmissionDTO;
import com.example.entity.Class;
import com.example.entity.Exam;
import com.example.entity.ExamClass;
import com.example.entity.ExamRecord;
import com.example.entity.ExamQuestion;
import com.example.entity.Question;
import com.example.mapper.ClassMapper;
import com.example.mapper.ExamClassMapper;
import com.example.mapper.ExamMapper;
import com.example.mapper.ExamRecordMapper;
import com.example.mapper.ExamQuestionMapper;
import com.example.mapper.QuestionMapper;
import com.example.service.ExamService;
import com.example.service.ExamAntiCheatingService;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;

@Service
public class ExamServiceImpl implements ExamService {

    private static final Logger log = LoggerFactory.getLogger(ExamServiceImpl.class);

    @Autowired
    private ExamMapper examMapper;
    
    @Autowired
    private ExamClassMapper examClassMapper;
    
    @Autowired
    private ExamRecordMapper examRecordMapper;

    @Autowired
    private ExamQuestionMapper examQuestionMapper;
    
    @Autowired
    private ClassMapper classMapper;
    
    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private QuestionMapper questionMapper;

    /**
     * 防作弊服务 - 用于记录和管理详细的可疑行为数据
     */
    @Autowired
    private ExamAntiCheatingService examAntiCheatingService;

    @Override
    public List<Exam> getAllExams() {
        return examMapper.selectList(null);
    }

    @Override
    public List<Exam> getTeacherExams(Long teacherId) {
        return examMapper.findByCreatorId(teacherId);
    }

    @Override
    public List<Exam> getClassExams(Long classId) {
        return examMapper.findByClassId(classId);
    }

    @Override
    public List<Exam> getStudentExams(Long studentId) {
        return examMapper.findByStudentId(studentId);
    }

    @Override
    public Exam getExamById(Long id) {
        Exam exam = examMapper.selectById(id);
        if (exam != null) {
            checkAndUpdateExamStatus(exam);
            exam = examMapper.selectById(id); // 重新获取更新后的状态
            
            // 加载关联的班级
            List<ExamClass> examClasses = examClassMapper.selectList(
                new QueryWrapper<ExamClass>().eq("exam_id", id)
            );
            List<Class> classes = new ArrayList<>();
            for (ExamClass examClass : examClasses) {
                Class classEntity = classMapper.selectById(examClass.getClassId());
                if (classEntity != null) {
                    classes.add(classEntity);
                }
            }
            exam.setClasses(classes);
            
            // 加载关联的题目
            List<ExamQuestion> examQuestions = examQuestionMapper.selectList(
                new QueryWrapper<ExamQuestion>()
                    .eq("exam_id", id)
                    .orderByAsc("`order`")
            );
            List<Question> questions = new ArrayList<>();
            for (ExamQuestion examQuestion : examQuestions) {
                Question question = questionMapper.selectById(examQuestion.getQuestionId());
                if (question != null) {
                    questions.add(question);
                }
            }
            exam.setQuestions(questions);
            
            return exam;
        }
        return null;
    }

    @Override
    @Transactional
    public ApiResponse<?> createExam(ExamRequest examRequest, Long teacherId) {
        try {
            // 验证班级ID是否存在
            for (Long classId : examRequest.getClassIds()) {
                Class classEntity = classMapper.selectById(classId);
                if (classEntity == null) {
                    return ApiResponse.error("班级ID " + classId + " 不存在");
                }
            }

            // 创建考试
            Exam exam = new Exam();
            exam.setTitle(examRequest.getTitle());
            exam.setDescription(examRequest.getDescription());
            exam.setStartTime(examRequest.getStartTime());
            exam.setEndTime(examRequest.getEndTime());
            exam.setDuration(examRequest.getDuration());
            exam.setPassScore(examRequest.getPassScore());
            exam.setStatus("DRAFT"); // 设置为草稿状态
            exam.setCreatorId(teacherId);
            exam.setCreateTime(LocalDateTime.now());
            exam.setUpdateTime(LocalDateTime.now());
            
            // 计算总分
            int totalScore = 0;
            if (examRequest.getQuestionIds() != null && !examRequest.getQuestionIds().isEmpty()) {
                for (Long questionId : examRequest.getQuestionIds()) {
                    Question question = questionMapper.selectById(questionId);
                    if (question == null) {
                        return ApiResponse.error("题目ID " + questionId + " 不存在");
                    }
                    totalScore += question.getScore();
                }
            }
            exam.setTotalScore(totalScore);
            
            examMapper.insert(exam);
            
            // 关联班级
            for (Long classId : examRequest.getClassIds()) {
                ExamClass examClass = new ExamClass();
                examClass.setExamId(exam.getId());
                examClass.setClassId(classId);
                examClass.setAssignTime(LocalDateTime.now());
                examClassMapper.insert(examClass);
            }
            
            // 关联题目
            if (examRequest.getQuestionIds() != null && !examRequest.getQuestionIds().isEmpty()) {
                int orderNum = 1;
                for (Long questionId : examRequest.getQuestionIds()) {
                    Question question = questionMapper.selectById(questionId);
                    ExamQuestion examQuestion = new ExamQuestion();
                    examQuestion.setExamId(exam.getId());
                    examQuestion.setQuestionId(questionId);
                    examQuestion.setScore(question.getScore()); // 使用题目原始分数
                    examQuestion.setOrder(orderNum++);
                    examQuestion.setQuestionType(question.getType()); // 设置题目类型
                    examQuestion.setSelectionMode("MANUAL"); // 设置选择方式
                    examQuestionMapper.insert(examQuestion);
                }
            }
            
            return ApiResponse.success("考试创建成功", exam);
        } catch (Exception e) {
            throw new RuntimeException("创建考试失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public ApiResponse<?> updateExam(Long id, ExamRequest examRequest, Long teacherId) {
        Exam exam = examMapper.selectById(id);


        if (exam == null) {
            return ApiResponse.error("考试不存在");
        }
        
        if (!exam.getCreatorId().equals(teacherId)) {
            return ApiResponse.error("您没有权限更新此考试");
        }
        
        if (exam.getPublished()) {
            return ApiResponse.error("已发布的考试不能修改");
        }
        
        // 更新考试信息
        exam.setTitle(examRequest.getTitle());
        exam.setDescription(examRequest.getDescription());
        exam.setStartTime(examRequest.getStartTime());
        exam.setDuration(examRequest.getDuration());
        exam.setTotalScore(examRequest.getTotalScore());
        exam.setPassScore(examRequest.getPassScore());
        exam.setRandomQuestions(examRequest.getRandomQuestions());
        exam.setPreventCheating(examRequest.getPreventCheating());
        exam.setShowResults(examRequest.getShowResults());
        exam.setUpdateTime(LocalDateTime.now());
        
        examMapper.updateById(exam);
        
        // 更新班级关联
        if (examRequest.getClassIds() != null) {
            // 删除现有关联
            examClassMapper.deleteByExamId(id);
            
            // 添加新关联
            for (Long classId : examRequest.getClassIds()) {
                ExamClass examClass = new ExamClass();
                examClass.setExamId(exam.getId());
                examClass.setClassId(classId);
                examClass.setAssignTime(LocalDateTime.now());
                examClassMapper.insert(examClass);
            }
        }
        
        // 更新题目关联
        if (examRequest.getQuestionIds() != null) {
            // 验证所有题目是否存在
            for (Long questionId : examRequest.getQuestionIds()) {
                Question question = questionMapper.selectById(questionId);
                if (question == null) {
                    return ApiResponse.error("题目ID " + questionId + " 不存在");
                }
            }
            
            // 删除现有题目关联
            QueryWrapper<ExamQuestion> wrapper = new QueryWrapper<>();
            wrapper.eq("exam_id", id);
            examQuestionMapper.delete(wrapper);
            
            // 添加新题目关联
            int orderNum = 1;
            for (Long questionId : examRequest.getQuestionIds()) {
                ExamQuestion examQuestion = new ExamQuestion();
                examQuestion.setExamId(exam.getId());
                examQuestion.setQuestionId(questionId);
                examQuestion.setScore(exam.getTotalScore() / examRequest.getQuestionIds().size()); // 平均分配分数
                examQuestion.setOrder(orderNum++);
                examQuestion.setQuestionType("MULTIPLE_CHOICE"); // 设置默认题目类型
                examQuestion.setSelectionMode("MANUAL"); // 设置选择方式
                examQuestionMapper.insert(examQuestion);
            }
        }
        
        return ApiResponse.success("考试更新成功", exam);
    }

    @Override
    @Transactional
    public ApiResponse<?> deleteExam(Long id, Long teacherId) {
        Exam exam = examMapper.selectById(id);
        
        if (exam == null) {
            return ApiResponse.error("考试不存在");
        }
        
        if (!exam.getCreatorId().equals(teacherId)) {
            return ApiResponse.error("您没有权限删除此考试");
        }
        
        // 检查是否已有学生参加
        QueryWrapper<ExamRecord> recordWrapper = new QueryWrapper<>();
        recordWrapper.eq("exam_id", id);
        long recordCount = examRecordMapper.selectCount(recordWrapper);
        
        if (recordCount > 0) {
            return ApiResponse.error("已有学生参加此考试，无法删除");
        }
        
        // 删除考试题目关联
        QueryWrapper<ExamQuestion> questionWrapper = new QueryWrapper<>();
        questionWrapper.eq("exam_id", id);
        examQuestionMapper.delete(questionWrapper);
        
        // 删除考试班级关联
        examClassMapper.deleteByExamId(id);
        
        // 删除考试
        examMapper.deleteById(id);
        
        return ApiResponse.success("考试删除成功", null);
    }

    @Override
    @Transactional
    public ApiResponse<?> publishExam(Long id, Long teacherId) {
        Exam exam = examMapper.selectById(id);
        
        if (exam == null) {
            return ApiResponse.error("考试不存在");
        }
        
        if (!exam.getCreatorId().equals(teacherId)) {
            return ApiResponse.error("您没有权限发布此考试");
        }
        
        // 检查当前状态
        String currentStatus = exam.getStatus();
        if (!"DRAFT".equals(currentStatus)) {
            return ApiResponse.error("只有草稿状态的考试可以发布");
        }
        
        // 发布考试
        exam.setPublished(true);
        exam.setStatus("PUBLISHED"); // 更新状态为已发布
        exam.setPublishTime(LocalDateTime.now());
        exam.setUpdateTime(LocalDateTime.now());
        
        examMapper.updateById(exam);
        
        return ApiResponse.success("考试发布成功", exam);
    }

    @Override
    @Transactional
    public ApiResponse<?> assignExamToClass(Long examId, Long classId, Long teacherId) {
        Exam exam = examMapper.selectById(examId);
        
        if (exam == null) {
            return ApiResponse.error("考试不存在");
        }
        
        if (!exam.getCreatorId().equals(teacherId)) {
            return ApiResponse.error("您没有权限分配此考试");
        }
        
        // 检查是否已分配
        ExamClass existingAssignment = examClassMapper.findByExamIdAndClassId(examId, classId);
        
        if (existingAssignment != null) {
            return ApiResponse.error("考试已分配给该班级");
        }
        
        // 创建新分配
        ExamClass examClass = new ExamClass();
        examClass.setExamId(examId);
        examClass.setClassId(classId);
        examClass.setAssignTime(LocalDateTime.now());
        
        examClassMapper.insert(examClass);
        
        return ApiResponse.success("考试成功分配到班级", examClass);
    }

    @Override
    @Transactional
    public ApiResponse<?> removeExamFromClass(Long examId, Long classId, Long teacherId) {
        Exam exam = examMapper.selectById(examId);
        
        if (exam == null) {
            return ApiResponse.error("考试不存在");
        }
        
        if (!exam.getCreatorId().equals(teacherId)) {
            return ApiResponse.error("您没有权限移除此考试");
        }
        
        // 检查是否存在分配
        ExamClass existingAssignment = examClassMapper.findByExamIdAndClassId(examId, classId);
        
        if (existingAssignment == null) {
            return ApiResponse.error("考试未分配给该班级");
        }
        
        // 检查是否已有学生参加
        QueryWrapper<ExamRecord> recordWrapper = new QueryWrapper<>();
        recordWrapper.eq("exam_id", examId).eq("class_id", classId);
        long recordCount = examRecordMapper.selectCount(recordWrapper);
        
        if (recordCount > 0) {
            return ApiResponse.error("已有学生参加此考试，无法移除");
        }
        
        // 移除分配
        examClassMapper.deleteByExamIdAndClassId(examId, classId);
        
        return ApiResponse.success("考试成功从班级移除", null);
    }

    @Override
    @Transactional
    public ExamRecord startExam(Long examId, Long studentId, Long classId) {
        Exam exam = examMapper.selectById(examId);
        
        if (exam == null) {
            throw new RuntimeException("考试不存在");
        }
        
        if (!exam.getPublished()) {
            throw new RuntimeException("考试尚未发布");
        }
        
        LocalDateTime now = LocalDateTime.now();
        
        if (now.isBefore(exam.getStartTime())) {
            throw new RuntimeException("考试尚未开始");
        }
        
        LocalDateTime endTime = exam.getStartTime().plusMinutes(exam.getDuration());
        
        if (now.isAfter(endTime)) {
            throw new RuntimeException("考试已结束");
        }
        
        // 检查班级分配
        ExamClass examClass = examClassMapper.findByExamIdAndClassId(examId, classId);
        
        if (examClass == null) {
            throw new RuntimeException("该考试未分配给此班级");
        }
        
        // 检查是否已经开始考试
        QueryWrapper<ExamRecord> recordWrapper = new QueryWrapper<>();
        recordWrapper.eq("exam_id", examId).eq("student_id", studentId);
        ExamRecord existingRecord = examRecordMapper.selectOne(recordWrapper);
        
        if (existingRecord != null) {
            if ("completed".equals(existingRecord.getStatus()) || "submitted".equals(existingRecord.getStatus())) {
                throw new RuntimeException("您已完成此考试，不能重新开始");
            }
            
            // 返回现有记录
            return existingRecord;
        }
        
        // 创建新考试记录
        ExamRecord record = new ExamRecord();
        record.setExamId(examId);
        record.setStudentId(studentId);
        record.setClassId(classId);
        record.setStartTime(LocalDateTime.now());
        record.setStatus("in_progress");
        record.setCreateTime(LocalDateTime.now());
        record.setUpdateTime(LocalDateTime.now());
        
        examRecordMapper.insert(record);
        
        return record;
    }

    @Override
    @Transactional
    public ApiResponse<?> submitExam(Long examId, Long studentId, String answers) {
        try {
            // 检查考试记录
            ExamRecord examRecord = examRecordMapper.selectOne(
                new QueryWrapper<ExamRecord>()
                    .eq("exam_id", examId)
                    .eq("student_id", studentId)
            );
            
            if (examRecord == null) {
                return ApiResponse.error("考试记录不存在");
            }
            
            if (!"IN_PROGRESS".equals(examRecord.getStatus())) {
                return ApiResponse.error("考试已结束或未开始");
            }
            
            // 解析提交的数据
            Map<String, Object> submittedData = objectMapper.readValue(answers, Map.class);
            
            // 提取答案和防作弊计数
            Map<String, String> examAnswers = (Map<String, String>) submittedData.get("answers");
            System.out.println("Submitted answers: " + examAnswers);
            
            // 获取考试题目
            List<ExamQuestion> examQuestions = examQuestionMapper.findByExamId(examId);
            Map<Long, Question> questionMap = new HashMap<>();
            for (ExamQuestion eq : examQuestions) {
                Question question = questionMapper.selectById(eq.getQuestionId());
                questionMap.put(eq.getQuestionId(), question);
            }
            
            // 自动评分
            double totalScore = 0.0;
            Map<String, Object> scoringDetails = new HashMap<>();
            List<Map<String, Object>> questionScores = new ArrayList<>();
            
            for (Map.Entry<String, String> entry : examAnswers.entrySet()) {
                Long questionId = Long.valueOf(entry.getKey());
                String studentAnswer = entry.getValue();
                Question question = questionMap.get(questionId);
                ExamQuestion examQuestion = examQuestions.stream()
                    .filter(eq -> eq.getQuestionId().equals(questionId))
                    .findFirst()
                    .orElse(null);
                
                if (question != null && examQuestion != null) {
                    Map<String, Object> questionScore = new HashMap<>();
                    questionScore.put("questionId", questionId);
                    questionScore.put("type", question.getType());
                    questionScore.put("maxScore", examQuestion.getScore());
                    
                    // 根据题目类型进行评分
                    double score = 0.0;
                    String questionType = question.getType();
                    List<String> correctAnswers = question.getAnswers(); // 假设返回 List<String>

                    if (("SINGLE_CHOICE".equals(questionType) || "TRUE_FALSE".equals(questionType))
                            && correctAnswers != null && !correctAnswers.isEmpty()) {
                        // 单选题和判断题：期望列表只有一个正确答案
                        if (correctAnswers.get(0).equals(studentAnswer)) {
                            score = examQuestion.getScore();
                        }
                        questionScore.put("autoGraded", true);
                    } else if ("MULTIPLE_CHOICE".equals(questionType) && correctAnswers != null) {
                        // 多选题: 当前逻辑是检查提交的单个答案字符串是否存在于正确答案列表中。
                        // 这可能需要根据前端提交多选答案的方式进行调整（例如，如果前端提交的是数组）。
                        // 目前，如果学生提交的单个选项是正确选项之一，就给满分。
                        if (correctAnswers.contains(studentAnswer)) {
                            score = examQuestion.getScore();
                        }
                        questionScore.put("autoGraded", true);
                    } else {
                        // 其他题型（填空、简答等）需要人工评分
                        questionScore.put("autoGraded", false);
                        questionScore.put("needsManualGrading", true);
                    }
                    
                    questionScore.put("score", score);
                    questionScore.put("studentAnswer", studentAnswer);
                    questionScore.put("correctAnswer", question.getAnswers());
                    questionScores.add(questionScore);
                    
                    totalScore += score;
                }
            }
            
            scoringDetails.put("questionScores", questionScores);
            
            // 更新考试记录
            examRecord.setAnswers(objectMapper.writeValueAsString(examAnswers));
            examRecord.setScoringDetails(objectMapper.writeValueAsString(scoringDetails));
            
            // 处理防作弊相关计数 - 同时保存到ExamRecord和详细记录表
            Map<String, Integer> behaviorCounts = new HashMap<>();
            
            if (submittedData.containsKey("keyboard_shortcut_count")) {
                Integer count = ((Number) submittedData.get("keyboard_shortcut_count")).intValue();
                examRecord.setKeyboardShortcutCount(count);
                behaviorCounts.put("keyboard_shortcut_count", count);
            }
            if (submittedData.containsKey("copy_paste_count")) {
                Integer count = ((Number) submittedData.get("copy_paste_count")).intValue();
                examRecord.setCopyPasteCount(count);
                behaviorCounts.put("copy_paste_count", count);
            }
            if (submittedData.containsKey("tab_switch_count")) {
                Integer count = ((Number) submittedData.get("tab_switch_count")).intValue();
                examRecord.setTabSwitchCount(count);
                behaviorCounts.put("tab_switch_count", count);
            }
            if (submittedData.containsKey("suspicious_level")) {
                examRecord.setSuspiciousLevel(((Number) submittedData.get("suspicious_level")).intValue());
            }
            
            // 使用新的防作弊服务批量记录可疑行为详情
            try {
                examAntiCheatingService.batchRecordBehaviorCounts(examId, studentId, behaviorCounts);
                log.info("成功记录考试提交的可疑行为详情 - 考试ID: {}, 学生ID: {}", examId, studentId);
            } catch (Exception e) {
                log.warn("记录可疑行为详情失败，但不影响考试提交 - 考试ID: {}, 学生ID: {}, 错误: {}", 
                        examId, studentId, e.getMessage());
            }
            
            // 检查是否需要人工评分
            boolean needsManualGrading = questionScores.stream()
                .anyMatch(qs -> Boolean.TRUE.equals(qs.get("needsManualGrading")));
            
            // 更新状态和时间
            examRecord.setStatus("SUBMITTED");
            examRecord.setSubmitTime(LocalDateTime.now());
            examRecord.setUpdateTime(LocalDateTime.now());
            
            if (!needsManualGrading) {
                // 如果不需要人工评分,直接设置为已批改
                examRecord.setScore(totalScore);
                examRecord.setStatus("MARKED");
                examRecord.setMarkingStatus("COMPLETED");
                examRecord.setMarkingEndTime(LocalDateTime.now());
                
                // 添加汇总评分信息到 scoringDetails
                scoringDetails.put("autoGradedTotal", totalScore);
                scoringDetails.put("manualGradedTotal", 0.0); // 没有人工评分项，所以是 0
                scoringDetails.put("finalTotalScore", totalScore);
                
                // 判断是否通过
                Exam exam = examMapper.selectById(examId);
                if (exam != null && exam.getPassScore() != null) {
                    examRecord.setPassed(totalScore >= exam.getPassScore());
                }
            } else {
                // 需要人工评分,设置初始分数 (仅自动评分部分)
                examRecord.setScore(totalScore);
                examRecord.setMarkingStatus("PENDING");
                // 对于需要人工批改的情况，也添加已有的自动评分总分信息
                scoringDetails.put("autoGradedTotal", totalScore);
                // pendingTotal 可以在 startMarking 时再计算加入
            }
            
            // 保存更新
            examRecordMapper.updateById(examRecord);
            
            return ApiResponse.success("考试提交成功", examRecord);
        } catch (Exception e) {
            log.error("提交考试失败", e);
            return ApiResponse.error("提交考试失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public ApiResponse<?> saveQuestionAnswer(Long examId, Long questionId, Long studentId, String answer) {
        try {
            // 检查考试记录
            ExamRecord examRecord = examRecordMapper.selectOne(
                new QueryWrapper<ExamRecord>()
                    .eq("exam_id", examId)
                    .eq("student_id", studentId)
            );
            
            if (examRecord == null) {
                return ApiResponse.error("考试记录不存在");
            }
            
            if (!"IN_PROGRESS".equals(examRecord.getStatus())) {
                return ApiResponse.error("考试已结束或未开始");
            }
            
            // 获取现有答案
            Map<String, Object> answers;
            try {
                answers = objectMapper.readValue(examRecord.getAnswers(), Map.class);
            } catch (Exception e) {
                answers = new HashMap<>();
            }
            
            // 更新答案
            answers.put(questionId.toString(), answer);
            examRecord.setAnswers(objectMapper.writeValueAsString(answers));
            examRecord.setUpdateTime(LocalDateTime.now());
            examRecord.setLastActiveTime(LocalDateTime.now());
            
            // 保存更新
            examRecordMapper.updateById(examRecord);
            
            return ApiResponse.success("答案保存成功");
        } catch (Exception e) {
            return ApiResponse.error("保存答案失败：" + e.getMessage());
        }
    }

    @Override
    public List<ExamRecord> getExamRecords(Long examId) {
        QueryWrapper<ExamRecord> wrapper = new QueryWrapper<>();
        wrapper.eq("exam_id", examId);
        return examRecordMapper.selectList(wrapper);
    }

    @Override
    public ExamRecord getStudentExamRecord(Long examId, Long studentId) {
        QueryWrapper<ExamRecord> wrapper = new QueryWrapper<>();
        wrapper.eq("exam_id", examId).eq("student_id", studentId);
        return examRecordMapper.selectOne(wrapper);
    }

    @Override
    public ExamStatisticsDTO getExamStatistics(Long examId) {
        // 1. 获取考试基本信息
        Exam exam = examMapper.selectById(examId);
        if (exam == null) {
            throw new RuntimeException("考试不存在");
        }

        // 2. 获取考试记录
        List<ExamRecord> records = examRecordMapper.selectByExamId(examId);
        
        // 3. 统计基础数据
        int totalStudents = examClassMapper.countStudentsByExamId(examId);
        
        // 4. 统计已完成的考试（状态为MARKED的才算真正完成）
        long completed = records.stream()
            .filter(r -> "MARKED".equals(r.getStatus()))
            .count();
        
        // 5. 计算平均分（只计算已批改的考试）
        double totalScore = records.stream()
            .filter(r -> "MARKED".equals(r.getStatus()))
            .mapToDouble(ExamRecord::getScore)
            .sum();
        double averageScore = completed > 0 ? totalScore / completed : 0.0;
        
        // 6. 统计通过人数（需要考虑通过分数线）
        double passScore = exam.getPassScore() != null ? exam.getPassScore() : 60.0; // 默认60分通过
        long passed = records.stream()
            .filter(r -> "MARKED".equals(r.getStatus()) && r.getScore() >= passScore)
            .count();
        
        // 7. 计算比率
        double completionRate = totalStudents > 0 ? (double) completed / totalStudents : 0.0;
        double passRate = completed > 0 ? (double) passed / completed : 0.0;
        
        // 8. 构建并返回统计结果
        return ExamStatisticsDTO.builder()
                .examId(examId)
                .title(exam.getTitle())
                .totalScore(exam.getTotalScore().doubleValue())
                .totalStudents(totalStudents)
                .completed((int) completed)
                .passed((int) passed)
                .completionRate(completionRate)
                .averageScore(averageScore)
                .passRate(passRate)
                .build();
    }

    @Override
    @Transactional
    public ApiResponse<?> saveDraft(Long id, ExamRequest examRequest, Long teacherId) {
        // 检查考试是否存在
        Exam exam = examMapper.selectById(id);
        if (exam == null) {
            return ApiResponse.error("考试不存在");
        }

        // 检查权限
        if (!exam.getCreatorId().equals(teacherId)) {
            return ApiResponse.error("您没有权限保存此考试");
        }

        // 更新考试基本信息
        BeanUtils.copyProperties(examRequest, exam);
        exam.setStatus("DRAFT"); // 设置为草稿状态
        exam.setUpdateTime(LocalDateTime.now());
        examMapper.updateById(exam);

        // 更新班级关联
        if (examRequest.getClassIds() != null) {
            // 删除现有关联
            examClassMapper.deleteByExamId(id);
            
            // 添加新关联
            for (Long classId : examRequest.getClassIds()) {
                ExamClass examClass = new ExamClass();
                examClass.setExamId(exam.getId());
                examClass.setClassId(classId);
                examClass.setAssignTime(LocalDateTime.now());
                examClassMapper.insert(examClass);
            }
        }

        // 更新题目关联
        if (examRequest.getQuestionIds() != null) {
            // 验证所有题目是否存在
            for (Long questionId : examRequest.getQuestionIds()) {
                Question question = questionMapper.selectById(questionId);
                if (question == null) {
                    return ApiResponse.error("题目ID " + questionId + " 不存在");
                }
            }
            
            // 删除现有题目关联
            QueryWrapper<ExamQuestion> wrapper = new QueryWrapper<>();
            wrapper.eq("exam_id", id);
            examQuestionMapper.delete(wrapper);
            
            // 添加新题目关联
            int orderNum = 1;
            for (Long questionId : examRequest.getQuestionIds()) {
                ExamQuestion examQuestion = new ExamQuestion();
                examQuestion.setExamId(exam.getId());
                examQuestion.setQuestionId(questionId);
                examQuestion.setScore(exam.getTotalScore() / examRequest.getQuestionIds().size()); // 平均分配分数
                examQuestion.setOrder(orderNum++);
                examQuestion.setQuestionType("MULTIPLE_CHOICE"); // 设置默认题目类型
                examQuestion.setSelectionMode("MANUAL"); // 设置选择方式
                examQuestionMapper.insert(examQuestion);
            }
        }

        return ApiResponse.success("草稿保存成功", exam);
    }

    @Override
    public Map<String, Object> getStudentExamHistory(Long studentId) {
        Map<String, Object> history = new HashMap<>();
        
        // 获取学生的所有考试记录
        QueryWrapper<ExamRecord> wrapper = new QueryWrapper<>();
        wrapper.eq("student_id", studentId);
        List<ExamRecord> records = examRecordMapper.selectList(wrapper);
        
        // 统计数据
        int totalExams = records.size();
        int completedExams = 0;
        int passedExams = 0;
        double totalScore = 0;
        
        for (ExamRecord record : records) {
            if ("SUBMITTED".equals(record.getStatus()) || "MARKED".equals(record.getStatus())) {
                completedExams++;
                if (record.getScore() != null) {
                    totalScore += record.getScore();
                    if (record.getPassed()) {
                        passedExams++;
                    }
                }
            }
        }
        
        // 填充统计数据
        history.put("studentId", studentId);
        history.put("totalExams", totalExams);
        history.put("completedExams", completedExams);
        history.put("passedExams", passedExams);
        history.put("averageScore", completedExams > 0 ? totalScore / completedExams : 0);
        history.put("passRate", completedExams > 0 ? (double) passedExams / completedExams : 0);
        history.put("examRecords", records);
        
        return history;
    }

    @Override
    public Map<String, Object> getClassExamStatistics(Long examId, Long classId) {
        Map<String, Object> statistics = new HashMap<>();
        
        // 获取班级的考试记录
        QueryWrapper<ExamRecord> wrapper = new QueryWrapper<>();
        wrapper.eq("exam_id", examId).eq("class_id", classId);
        List<ExamRecord> records = examRecordMapper.selectList(wrapper);
        
        // 统计数据
        int totalStudents = records.size();
        int completedCount = 0;
        int passedCount = 0;
        double totalScore = 0;
        
        for (ExamRecord record : records) {
            if ("SUBMITTED".equals(record.getStatus()) || "MARKED".equals(record.getStatus())) {
                completedCount++;
                if (record.getScore() != null) {
                    totalScore += record.getScore();
                    if (record.getPassed()) {
                        passedCount++;
                    }
                }
            }
        }
        
        // 填充统计数据
        statistics.put("examId", examId);
        statistics.put("classId", classId);
        statistics.put("totalStudents", totalStudents);
        statistics.put("completedCount", completedCount);
        statistics.put("passedCount", passedCount);
        statistics.put("averageScore", completedCount > 0 ? totalScore / completedCount : 0);
        statistics.put("passRate", completedCount > 0 ? (double) passedCount / completedCount : 0);
        statistics.put("records", records);
        
        return statistics;
    }

    @Override
    public List<Map<String, Object>> getSuspiciousActions(Long examId) {
        // 获取考试的所有可疑行为记录
        QueryWrapper<ExamRecord> wrapper = new QueryWrapper<>();
        wrapper.eq("exam_id", examId)
              .gt("suspicious_level", 0)
              .orderByDesc("suspicious_level");
        
        List<ExamRecord> records = examRecordMapper.selectList(wrapper);
        List<Map<String, Object>> actions = new ArrayList<>();
        
        for (ExamRecord record : records) {
            Map<String, Object> action = new HashMap<>();
            action.put("recordId", record.getId());
            action.put("studentId", record.getStudentId());
            action.put("suspiciousLevel", record.getSuspiciousLevel());
            action.put("keyboardShortcutCount", record.getKeyboardShortcutCount());
            action.put("copyPasteCount", record.getCopyPasteCount());
            action.put("tabSwitchCount", record.getTabSwitchCount());
            action.put("examTime", record.getStartTime());
            actions.add(action);
        }
        
        return actions;
    }

    @Override
    public List<Map<String, Object>> getStudentSuspiciousActions(Long examId, Long studentId) {
        // 获取特定学生的可疑行为记录
        QueryWrapper<ExamRecord> wrapper = new QueryWrapper<>();
        wrapper.eq("exam_id", examId)
              .eq("student_id", studentId)
              .gt("suspicious_level", 0)
              .orderByDesc("suspicious_level");
        
        List<ExamRecord> records = examRecordMapper.selectList(wrapper);
        List<Map<String, Object>> actions = new ArrayList<>();
        
        for (ExamRecord record : records) {
            Map<String, Object> action = new HashMap<>();
            action.put("recordId", record.getId());
            action.put("suspiciousLevel", record.getSuspiciousLevel());
            action.put("keyboardShortcutCount", record.getKeyboardShortcutCount());
            action.put("copyPasteCount", record.getCopyPasteCount());
            action.put("tabSwitchCount", record.getTabSwitchCount());
            action.put("examTime", record.getStartTime());
            actions.add(action);
        }
        
        return actions;
    }

    @Override
    @Transactional
    public ApiResponse<?> recordSuspiciousAction(Long examId, Long studentId, String actionType, String details) {
        try {
            // 首先记录到详细记录表
            String riskLevel = determineRiskLevel(actionType, details);
            ApiResponse<?> detailRecordResult = examAntiCheatingService.recordSuspiciousBehavior(
                    examId, studentId, actionType, details, riskLevel);
            
            if (!detailRecordResult.isSuccess()) {
                log.warn("记录详细可疑行为失败: {}", detailRecordResult.getMessage());
            }
            
            // 然后更新ExamRecord中的计数（保持向后兼容）
            QueryWrapper<ExamRecord> wrapper = new QueryWrapper<>();
            wrapper.eq("exam_id", examId).eq("student_id", studentId);
            ExamRecord record = examRecordMapper.selectOne(wrapper);
            
            if (record == null) {
                return ApiResponse.error("未找到考试记录");
            }
            
            // 更新可疑行为记录
            int currentLevel = record.getSuspiciousLevel() != null ? record.getSuspiciousLevel() : 0;
            record.setSuspiciousLevel(currentLevel + 1);
            
            // 根据actionType更新相应计数
            if ("KEYBOARD_SHORTCUT".equals(actionType)) {
                record.setKeyboardShortcutCount((record.getKeyboardShortcutCount() != null ? record.getKeyboardShortcutCount() : 0) + 1);
            } else if ("COPY_PASTE".equals(actionType)) {
                record.setCopyPasteCount((record.getCopyPasteCount() != null ? record.getCopyPasteCount() : 0) + 1);
            } else if ("TAB_SWITCH".equals(actionType)) {
                record.setTabSwitchCount((record.getTabSwitchCount() != null ? record.getTabSwitchCount() : 0) + 1);
            }
            
            record.setUpdateTime(LocalDateTime.now());
            examRecordMapper.updateById(record);
            
            log.info("记录可疑行为成功 - 考试ID: {}, 学生ID: {}, 行为类型: {}", examId, studentId, actionType);
            return ApiResponse.success("可疑行为记录成功", record);
            
        } catch (Exception e) {
            log.error("记录可疑行为失败", e);
            return ApiResponse.error("记录可疑行为失败：" + e.getMessage());
        }
    }
    
    /**
     * 根据行为类型和详情确定风险等级
     */
    private String determineRiskLevel(String actionType, String details) {
        switch (actionType) {
            case "KEYBOARD_SHORTCUT":
                return "HIGH"; // 键盘快捷键通常是高风险
            case "COPY_PASTE":
                return "CRITICAL"; // 复制粘贴是严重风险
            case "TAB_SWITCH":
                return "MEDIUM"; // 切换标签是中等风险
            case "MOUSE_LEAVE":
                return "LOW"; // 鼠标离开是低风险
            case "FULLSCREEN_EXIT":
                return "HIGH"; // 退出全屏是高风险
            case "WINDOW_FOCUS_LOSS":
                return "MEDIUM"; // 窗口失焦是中等风险
            default:
                return "MEDIUM"; // 默认中等风险
        }
    }

    @Override
    @Transactional
    public ApiResponse<?> startMarking(Long recordId, Long teacherId) {
        ExamRecord record = examRecordMapper.selectById(recordId);
        if (record == null) {
            return ApiResponse.error("考试记录不存在");
        }
        
        // 检查考试状态
        if (!"SUBMITTED".equals(record.getStatus())) {
            return ApiResponse.error("该考试未提交，无法开始批改");
        }
        
        // 检查是否已经有人在批改
        if ("IN_PROGRESS".equals(record.getMarkingStatus()) && 
            !teacherId.equals(record.getMarkingTeacherId())) {
            return ApiResponse.error("该考试已有其他教师在批改中");
        }
        
        // 更新批改状态
        record.setMarkingStatus("IN_PROGRESS");
        record.setMarkingTeacherId(teacherId);
        record.setMarkingStartTime(LocalDateTime.now());
        
        // 获取考试题目信息
        List<ExamQuestion> examQuestions = examQuestionMapper.findByExamId(record.getExamId());
        List<Map<String, Object>> questions = new ArrayList<>();
        Map<Long, Question> questionMap = new HashMap<>();
        
        for (ExamQuestion eq : examQuestions) {
            Question question = questionMapper.selectById(eq.getQuestionId());
            if (question != null) {
                // 保存到Map中供后续使用
                questionMap.put(eq.getQuestionId(), question);
                
                Map<String, Object> questionInfo = new HashMap<>();
                questionInfo.put("id", question.getId());
                questionInfo.put("content", question.getContent());
                questionInfo.put("type", question.getType());
                questionInfo.put("options", question.getOptions());
                questionInfo.put("answers", question.getAnswers());
                questionInfo.put("explanation", question.getExplanation());
                questionInfo.put("knowledgePoint", question.getKnowledgePoint());
                questionInfo.put("score", eq.getScore());
                questionInfo.put("order", eq.getOrder());
                questions.add(questionInfo);
            }
        }
        record.setQuestions(questions);
        
        // 解析scoringDetails
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            if (record.getScoringDetails() != null) {
                JsonNode scoringDetailsNode = objectMapper.readTree(record.getScoringDetails());
                Map<String, Object> formattedDetails = new HashMap<>();
                
                // 提取自动评分的题目和待批改的题目
                List<Map<String, Object>> autoGradedQuestions = new ArrayList<>();
                List<Map<String, Object>> pendingQuestions = new ArrayList<>();
                
                JsonNode questionScores = scoringDetailsNode.get("questionScores");
                if (questionScores != null && questionScores.isArray()) {
                    for (JsonNode question : questionScores) {
                        Map<String, Object> scoreMap = objectMapper.convertValue(question, Map.class);
                        Long questionId = Long.valueOf(scoreMap.get("questionId").toString());
                        
                        // 添加题目详细信息
                        Question fullQuestion = questionMap.get(questionId);
                        if (fullQuestion != null) {
                            scoreMap.put("content", fullQuestion.getContent());
                            scoreMap.put("options", fullQuestion.getOptions());
                            scoreMap.put("explanation", fullQuestion.getExplanation());
                            scoreMap.put("knowledgePoint", fullQuestion.getKnowledgePoint());
                        }
                        
                        if (Boolean.TRUE.equals(scoreMap.get("autoGraded"))) {
                            autoGradedQuestions.add(scoreMap);
                        } else {
                            pendingQuestions.add(scoreMap);
                        }
                    }
                }
                
                // 计算已得分和待批改分数
                double autoGradedTotal = autoGradedQuestions.stream()
                    .mapToDouble(q -> ((Number) q.get("score")).doubleValue())
                    .sum();
                
                double pendingTotal = pendingQuestions.stream()
                    .mapToDouble(q -> ((Number) q.get("maxScore")).doubleValue())
                    .sum();
                
                formattedDetails.put("autoGradedQuestions", autoGradedQuestions);
                formattedDetails.put("pendingQuestions", pendingQuestions);
                formattedDetails.put("autoGradedTotal", autoGradedTotal);
                formattedDetails.put("pendingTotal", pendingTotal);
                formattedDetails.put("maxPossibleScore", autoGradedTotal + pendingTotal);
                
                record.setScoringDetails(objectMapper.writeValueAsString(formattedDetails));
            }
        } catch (Exception e) {
            log.error("解析评分详情失败", e);
        }
        
        examRecordMapper.updateById(record);
        return ApiResponse.success("开始批改", record);
    }

    @Override
    @Transactional
    public ApiResponse<?> submitMarking(Long recordId, MarkingSubmissionDTO submission, Long teacherId) {
        ExamRecord record = examRecordMapper.selectById(recordId);
        if (record == null) {
            return ApiResponse.error("考试记录不存在");
        }

        // 验证批改权限
        if (!"IN_PROGRESS".equals(record.getMarkingStatus()) || 
            !teacherId.equals(record.getMarkingTeacherId())) {
            return ApiResponse.error("无权提交批改");
        }

        try {
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Object> scoringDetails;
            List<Map<String, Object>> questionScores;

            // 获取现有的评分详情
            if (record.getScoringDetails() == null || record.getScoringDetails().isEmpty()) {
                scoringDetails = new HashMap<>();
                questionScores = new ArrayList<>();
            } else {
                // 保留原有的评分信息
                scoringDetails = objectMapper.readValue(record.getScoringDetails(), Map.class);
                questionScores = (List<Map<String, Object>>) scoringDetails.get("questionScores");
                if (questionScores == null) {
                    questionScores = new ArrayList<>();
                }
            }

            // 获取已有的自动评分总分（从exam_records表中的score字段）
            double existingAutoGradedScore = record.getScore() != null ? record.getScore() : 0.0;

            // 计算手动评分部分的总分
            double manualGradedTotal = 0.0;
            if (submission.getQuestionScores() != null) {
                for (MarkingSubmissionDTO.QuestionScoreDTO questionScore : submission.getQuestionScores()) {
                    manualGradedTotal += questionScore.getScore();
                    boolean found = false;
                    for (Map<String, Object> existingScore : questionScores) {
                        if (existingScore.get("questionId").toString().equals(questionScore.getQuestionId().toString())) {
                            existingScore.put("score", questionScore.getScore());
                            existingScore.put("comments", questionScore.getComments());
                            existingScore.put("manuallyGraded", true);
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        Map<String, Object> newScore = new HashMap<>();
                        newScore.put("questionId", questionScore.getQuestionId());
                        newScore.put("score", questionScore.getScore());
                        newScore.put("comments", questionScore.getComments());
                        newScore.put("manuallyGraded", true);
                        questionScores.add(newScore);
                    }
                }
            }

            // 计算最终总分（已有的自动评分 + 新的手动评分）
            double finalTotalScore = existingAutoGradedScore + manualGradedTotal;

            // 更新评分详情
            scoringDetails.put("questionScores", questionScores);
            scoringDetails.put("autoGradedTotal", existingAutoGradedScore);
            scoringDetails.put("manualGradedTotal", manualGradedTotal);
            scoringDetails.put("finalTotalScore", finalTotalScore);

            // 更新考试记录
            record.setScore(finalTotalScore);
            record.setMarkingComments(submission.getComments());
            record.setMarkingStatus("COMPLETED");
            record.setMarkingEndTime(LocalDateTime.now());
            record.setStatus("MARKED");
            record.setScoringDetails(objectMapper.writeValueAsString(scoringDetails));

            // 判断是否通过
            Exam exam = examMapper.selectById(record.getExamId());
            if (exam != null && exam.getPassScore() != null) {
                record.setPassed(finalTotalScore >= exam.getPassScore());
            }

            examRecordMapper.updateById(record);
            return ApiResponse.success("批改完成", record);
        } catch (Exception e) {
            log.error("提交批改失败", e);
            return ApiResponse.error("提交批改失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public ApiResponse<?> startExam(Long examId, Long teacherId) {
        Exam exam = examMapper.selectById(examId);
        
        if (exam == null) {
            return ApiResponse.error("考试不存在");
        }
        
        if (!exam.getCreatorId().equals(teacherId)) {
            return ApiResponse.error("您没有权限开始此考试");
        }
        
        // 检查当前状态
        String currentStatus = exam.getStatus();
        if (!"PUBLISHED".equals(currentStatus)) {
            return ApiResponse.error("只有已发布的考试可以开始");
        }
        
        exam.setStatus("IN_PROGRESS");
        exam.setUpdateTime(LocalDateTime.now());
        examMapper.updateById(exam);
        
        return ApiResponse.success("考试已开始", exam);
    }
    
    @Override
    @Transactional
    public ApiResponse<?> endExam(Long examId, Long teacherId) {
        Exam exam = examMapper.selectById(examId);
        
        if (exam == null) {
            return ApiResponse.error("考试不存在");
        }
        
        if (!exam.getCreatorId().equals(teacherId)) {
            return ApiResponse.error("您没有权限结束此考试");
        }
        
        // 检查当前状态
        String currentStatus = exam.getStatus();
        if (!"IN_PROGRESS".equals(currentStatus)) {
            return ApiResponse.error("只有进行中的考试可以结束");
        }
        
        exam.setStatus("ENDED");
        exam.setUpdateTime(LocalDateTime.now());
        examMapper.updateById(exam);
        
        return ApiResponse.success("考试已结束", exam);
    }
    
    @Override
    @Transactional
    public ApiResponse<?> startExamByStudent(Long examId, Long studentId, Long classId) {
        try {
            // 检查考试是否存在
            Exam exam = examMapper.selectById(examId);
            if (exam == null) {
                return ApiResponse.error("考试不存在");
            }

            // 检查考试时间窗口
            LocalDateTime now = LocalDateTime.now();
            if (now.isBefore(exam.getStartTime())) {
                return ApiResponse.error("考试还未开始，请在" + exam.getStartTime() + "后参加考试");
            }
            if (now.isAfter(exam.getEndTime())) {
                return ApiResponse.error("考试时间窗口已结束");
            }

            // 检查考试状态
            if (!"IN_PROGRESS".equals(exam.getStatus())) {
                if ("DRAFT".equals(exam.getStatus())) {
                    return ApiResponse.error("考试未发布");
                } else if ("ENDED".equals(exam.getStatus())) {
                    return ApiResponse.error("考试已结束");
                }
            }

            // 检查学生是否有权限参加考试
            ExamClass examClass = examClassMapper.selectOne(
                new QueryWrapper<ExamClass>()
                    .eq("exam_id", examId)
                    .eq("class_id", classId)
            );
            if (examClass == null) {
                return ApiResponse.error("该班级未分配此考试");
            }

            // 检查是否已经开始考试
            ExamRecord existingRecord = examRecordMapper.selectOne(
                new QueryWrapper<ExamRecord>()
                    .eq("exam_id", examId)
                    .eq("student_id", studentId)
            );
            
            // 获取考试题目
            List<ExamQuestion> examQuestions = examQuestionMapper.selectList(
                new QueryWrapper<ExamQuestion>()
                    .eq("exam_id", examId)
                    .orderByAsc("`order`")
            );
            
            // 构建题目信息
            List<Map<String, Object>> questionList = new ArrayList<>();
            for (ExamQuestion eq : examQuestions) {
                Question question = questionMapper.selectById(eq.getQuestionId());
                if (question != null) {
                    Map<String, Object> questionMap = new HashMap<>();
                    questionMap.put("id", question.getId());
                    questionMap.put("type", question.getType());
                    questionMap.put("content", question.getContent());
                    questionMap.put("score", eq.getScore());
                    questionMap.put("order", eq.getOrder());
                    
                    // 根据题目类型处理选项
                    if ("MULTIPLE_CHOICE".equals(question.getType()) || 
                        "SINGLE_CHOICE".equals(question.getType())) {
                        questionMap.put("options", question.getOptions());
                    }
                    
                    questionList.add(questionMap);
                }
            }

            if (existingRecord != null) {
                if ("SUBMITTED".equals(existingRecord.getStatus()) || "MARKED".equals(existingRecord.getStatus())) {
                    return ApiResponse.error("您已完成此考试，不能重复开始");
                }
                
                // 检查考试时长是否已超时
                LocalDateTime studentEndTime = existingRecord.getStartTime().plusMinutes(exam.getDuration());
                if (now.isAfter(studentEndTime)) {
                    existingRecord.setStatus("SUBMITTED");
                    existingRecord.setSubmitTime(now);
                    existingRecord.setEndTime(studentEndTime);
                    existingRecord.setUpdateTime(now);
                    existingRecord.setAutoSubmitted(true);
                    examRecordMapper.updateById(existingRecord);
                    return ApiResponse.error("您的考试时长(" + exam.getDuration() + "分钟)已用完，系统已自动提交");
                }
                
                // 检查是否在考试窗口内
                if (now.isAfter(exam.getEndTime())) {
                    existingRecord.setStatus("SUBMITTED");
                    existingRecord.setSubmitTime(now);
                    existingRecord.setEndTime(now);
                    existingRecord.setUpdateTime(now);
                    existingRecord.setAutoSubmitted(true);
                    examRecordMapper.updateById(existingRecord);
                    return ApiResponse.error("考试时间窗口已结束，系统已自动提交");
                }
                
                // 更新剩余时间
                long remainingSeconds = Math.min(
                    java.time.Duration.between(now, studentEndTime).getSeconds(),
                    java.time.Duration.between(now, exam.getEndTime()).getSeconds()
                );
                existingRecord.setRemainingTime((int) remainingSeconds);
                existingRecord.setUpdateTime(now);
                examRecordMapper.updateById(existingRecord);
                
                // 在考试记录中添加题目信息
                existingRecord.setQuestions(questionList);
                
                return ApiResponse.success("继续考试", existingRecord);
            }

            // 检查剩余时间是否足够完成考试
            long remainingWindowTime = java.time.Duration.between(now, exam.getEndTime()).toMinutes();
            if (remainingWindowTime < exam.getDuration()) {
                return ApiResponse.error("剩余考试时间不足" + exam.getDuration() + "分钟，无法开始考试");
            }

            // 创建考试记录
            ExamRecord examRecord = new ExamRecord();
            examRecord.setExamId(examId);
            examRecord.setStudentId(studentId);
            examRecord.setClassId(classId);
            examRecord.setStartTime(now);
            LocalDateTime studentEndTime = now.plusMinutes(exam.getDuration());
            LocalDateTime actualEndTime = studentEndTime.isBefore(exam.getEndTime()) ? studentEndTime : exam.getEndTime();
            examRecord.setEndTime(actualEndTime);
            examRecord.setRemainingTime((int) java.time.Duration.between(now, actualEndTime).getSeconds());
            examRecord.setStatus("IN_PROGRESS");
            examRecord.setLastActiveTime(now);
            examRecord.setCreateTime(now);
            examRecord.setUpdateTime(now);
            examRecord.setKeyboardShortcutCount(0);
            examRecord.setCopyPasteCount(0);
            examRecord.setTabSwitchCount(0);
            examRecord.setSuspiciousLevel(0);
            examRecord.setAutoSubmitted(false);
            
            // 初始化答案字段
            Map<String, String> emptyAnswers = new HashMap<>();
            for (ExamQuestion question : examQuestions) {
                emptyAnswers.put(question.getQuestionId().toString(), "");
            }
            examRecord.setAnswers(objectMapper.writeValueAsString(emptyAnswers));
            
            examRecordMapper.insert(examRecord);
            
            // 在考试记录中添加题目信息
            examRecord.setQuestions(questionList);
            
            return ApiResponse.success("开始考试成功", examRecord);
        } catch (Exception e) {
            log.error("开始考试失败", e);
            return ApiResponse.error("开始考试失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public ApiResponse<?> addQuestions(Long examId, List<Long> questionIds, Long teacherId) {
        Exam exam = examMapper.selectById(examId);
        
        if (exam == null) {
            return ApiResponse.error("考试不存在");
        }
        
        if (!exam.getCreatorId().equals(teacherId)) {
            return ApiResponse.error("您没有权限修改此考试");
        }
        
        if ("IN_PROGRESS".equals(exam.getStatus()) || "ENDED".equals(exam.getStatus())) {
            return ApiResponse.error("考试进行中或已结束，无法修改题目");
        }
        
        // 添加题目
        int order = 1;
        for (Long questionId : questionIds) {
            ExamQuestion examQuestion = new ExamQuestion();
            examQuestion.setExamId(examId);
            examQuestion.setQuestionId(questionId);
            examQuestion.setOrder(order++);
            examQuestion.setSelectionMode("MANUAL");
            examQuestion.setCreateTime(LocalDateTime.now());
            examQuestion.setUpdateTime(LocalDateTime.now());
            
            examQuestionMapper.insert(examQuestion);
        }
        
        return ApiResponse.success("题目添加成功", null);
    }
    
    @Override
    @Transactional
    public ApiResponse<?> removeQuestions(Long examId, List<Long> questionIds, Long teacherId) {
        Exam exam = examMapper.selectById(examId);
        
        if (exam == null) {
            return ApiResponse.error("考试不存在");
        }
        
        if (!exam.getCreatorId().equals(teacherId)) {
            return ApiResponse.error("您没有权限修改此考试");
        }
        
        if ("IN_PROGRESS".equals(exam.getStatus()) || "ENDED".equals(exam.getStatus())) {
            return ApiResponse.error("考试进行中或已结束，无法修改题目");
        }
        
        // 删除题目
        QueryWrapper<ExamQuestion> wrapper = new QueryWrapper<>();
        wrapper.eq("exam_id", examId)
              .in("question_id", questionIds);
        examQuestionMapper.delete(wrapper);
        
        return ApiResponse.success("题目移除成功", null);
    }
    
    @Override
    @Transactional
    public ApiResponse<?> generateRandomQuestions(Long examId, ExamRequest request, Long teacherId) {
        Exam exam = examMapper.selectById(examId);
        
        if (exam == null) {
            return ApiResponse.error("考试不存在");
        }
        
        if (!exam.getCreatorId().equals(teacherId)) {
            return ApiResponse.error("您没有权限修改此考试");
        }
        
        if ("IN_PROGRESS".equals(exam.getStatus()) || "ENDED".equals(exam.getStatus())) {
            return ApiResponse.error("考试进行中或已结束，无法修改题目");
        }
        
        // 根据规则随机生成题目
        // TODO: 实现随机题目生成逻辑
        
        return ApiResponse.success("随机题目生成成功", null);
    }

    /**
     * 检查并更新考试状态
     */
    private void checkAndUpdateExamStatus(Exam exam) {
        if (exam == null) return;
        
        LocalDateTime now = LocalDateTime.now();
        String currentStatus = exam.getStatus();
        boolean needUpdate = false;

        // 如果考试已发布，检查是否应该开始
        if ("PUBLISHED".equals(currentStatus)) {
            if (now.isAfter(exam.getStartTime()) || now.equals(exam.getStartTime())) {
                exam.setStatus("IN_PROGRESS");
                needUpdate = true;
                log.info("考试[{}]自动开始", exam.getId());
            }
        }
        
        // 如果考试进行中，检查是否应该结束
        if ("IN_PROGRESS".equals(currentStatus)) {
            // 检查所有进行中的考试记录
            QueryWrapper<ExamRecord> wrapper = new QueryWrapper<>();
            wrapper.eq("exam_id", exam.getId())
                  .eq("status", "IN_PROGRESS");
            
            List<ExamRecord> records = examRecordMapper.selectList(wrapper);
            
            for (ExamRecord record : records) {
                LocalDateTime recordEndTime = record.getStartTime().plusMinutes(exam.getDuration());
                if (now.isAfter(recordEndTime)) {
                    // 如果超过了考试时长，自动提交
                    record.setStatus("SUBMITTED");
                    record.setSubmitTime(now);
                    record.setUpdateTime(now);
                    record.setAutoSubmitted(true);
                    examRecordMapper.updateById(record);
                    log.info("考试记录[{}]已自动提交（超时）", record.getId());
                }
            }

            // 如果所有考试记录都已结束，且当前时间超过考试窗口结束时间，则结束考试
            if (now.isAfter(exam.getEndTime())) {
                exam.setStatus("ENDED");
                needUpdate = true;
                log.info("考试[{}]自动结束（考试窗口结束）", exam.getId());
            }
        }

        if (needUpdate) {
            exam.setUpdateTime(LocalDateTime.now());
            examMapper.updateById(exam);
        }
    }

    /**
     * 自动提交未完成的考试
     */
    private void autoSubmitUnfinishedExams(Long examId) {
        // 查找所有未完成的考试记录
        List<ExamRecord> unfinishedRecords = examRecordMapper.selectList(
            new QueryWrapper<ExamRecord>()
                .eq("exam_id", examId)
                .eq("status", "IN_PROGRESS")
        );
        
        LocalDateTime now = LocalDateTime.now();
        
        for (ExamRecord record : unfinishedRecords) {
            record.setStatus("SUBMITTED");
            record.setSubmitTime(now);
            record.setUpdateTime(now);
            record.setAutoSubmitted(true);
            // 设置默认的可疑行为计数
            record.setKeyboardShortcutCount(record.getKeyboardShortcutCount() != null ? record.getKeyboardShortcutCount() : 0);
            record.setCopyPasteCount(record.getCopyPasteCount() != null ? record.getCopyPasteCount() : 0);
            record.setTabSwitchCount(record.getTabSwitchCount() != null ? record.getTabSwitchCount() : 0);
            record.setSuspiciousLevel(calculateSuspiciousLevel(record));
            
            examRecordMapper.updateById(record);
        }
    }

    private int calculateSuspiciousLevel(ExamRecord record) {
        int level = 0;
        if (record.getKeyboardShortcutCount() != null && record.getKeyboardShortcutCount() > 5) level++;
        if (record.getCopyPasteCount() != null && record.getCopyPasteCount() > 3) level++;
        if (record.getTabSwitchCount() != null && record.getTabSwitchCount() > 3) level++;
        return Math.min(level, 5);  // 最高5级
    }

    /**
     * 定时检查和更新考试状态
     * 每30秒执行一次
     */
    @Scheduled(fixedRate = 30000) // 每30秒执行一次
    public void scheduledCheckExamStatus() {
        try {
            // 获取所有需要检查的考试
            QueryWrapper<Exam> wrapper = new QueryWrapper<>();
            wrapper.in("status", "PUBLISHED", "IN_PROGRESS")
                  .le("start_time", LocalDateTime.now()); // 只检查开始时间小于等于当前时间的考试
            
            List<Exam> exams = examMapper.selectList(wrapper);
            
            // 对每个考试执行状态检查
            for (Exam exam : exams) {
                checkAndUpdateExamStatus(exam);
            }
        } catch (Exception e) {
            log.error("定时检查考试状态时发生错误", e);
        }
    }

    /**
     * 定时检查单个考试的状态和学生答题时间
     * 每30秒执行一次
     */
    @Scheduled(fixedRate = 30000) // 每30秒执行一次
    public void scheduledCheckStudentExamTime() {
        try {
            // 获取所有进行中的考试记录
            QueryWrapper<ExamRecord> recordWrapper = new QueryWrapper<>();
            recordWrapper.eq("status", "IN_PROGRESS");
            List<ExamRecord> records = examRecordMapper.selectList(recordWrapper);

            LocalDateTime now = LocalDateTime.now();
            
            for (ExamRecord record : records) {
                // 获取考试信息
                Exam exam = examMapper.selectById(record.getExamId());
                if (exam == null) continue;

                // 检查学生个人考试时间是否结束
                LocalDateTime studentEndTime = record.getStartTime().plusMinutes(exam.getDuration());
                if (now.isAfter(studentEndTime)) {
                    // 如果超过了考试时长，自动提交
                    record.setStatus("SUBMITTED");
                    record.setSubmitTime(now);
                    record.setUpdateTime(now);
                    record.setAutoSubmitted(true);
                    examRecordMapper.updateById(record);
                    log.info("考试记录[{}]已自动提交（学生个人时间到期）", record.getId());
                    continue;
                }
                
                // 检查考试整体时间窗口
                if (now.isAfter(exam.getEndTime())) {
                    record.setStatus("SUBMITTED");
                    record.setSubmitTime(now);
                    record.setUpdateTime(now);
                    record.setAutoSubmitted(true);
                    examRecordMapper.updateById(record);
                    log.info("考试记录[{}]已自动提交（考试时间窗口结束）", record.getId());
                }
            }
        } catch (Exception e) {
            log.error("定时检查学生考试时间时发生错误", e);
        }
    }

    @Override
    public ApiResponse<?> getRemainingTime(Long examId, Long studentId) {
        try {
            // 查找学生正在进行的考试记录
            ExamRecord examRecord = examRecordMapper.selectOne(
                new QueryWrapper<ExamRecord>()
                    .eq("exam_id", examId)
                    .eq("student_id", studentId)
                    .eq("status", "IN_PROGRESS")
            );

            if (examRecord == null) {
                return ApiResponse.error("未找到进行中的考试记录");
            }

            // 获取考试信息以确保考试仍在进行中
            Exam exam = examMapper.selectById(examId);
            if (exam == null || !"IN_PROGRESS".equals(exam.getStatus())) {
                 // 如果考试本身已结束，也更新学生记录状态
                 if (examRecord.getStatus().equals("IN_PROGRESS")) {
                     examRecord.setStatus("SUBMITTED"); // 或 TIMEOUT
                     examRecord.setUpdateTime(LocalDateTime.now());
                     examRecordMapper.updateById(examRecord);
                 }
                 return ApiResponse.error("考试已结束");
            }

            // 计算剩余时间
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime studentEndTime = examRecord.getEndTime(); // 使用学生记录的结束时间

            if (now.isAfter(studentEndTime)) {
                // 如果学生自己的时间已到，自动提交
                 examRecord.setStatus("SUBMITTED"); // 或 TIMEOUT
                 examRecord.setUpdateTime(LocalDateTime.now());
                 examRecord.setAutoSubmitted(true);
                 examRecordMapper.updateById(examRecord);
                 return ApiResponse.success("考试时间已到", 0);
            }
            
            // 同时考虑考试的全局结束时间
            LocalDateTime examOverallEndTime = exam.getEndTime();
            LocalDateTime actualEndTime = studentEndTime.isBefore(examOverallEndTime) ? studentEndTime : examOverallEndTime;
            
            if (now.isAfter(actualEndTime)) {
                // 如果已经超过了实际应该结束的时间
                 examRecord.setStatus("SUBMITTED");
                 examRecord.setUpdateTime(LocalDateTime.now());
                 examRecord.setAutoSubmitted(true);
                 examRecordMapper.updateById(examRecord);
                 return ApiResponse.success("考试时间已到", 0);
            }

            long remainingSeconds = java.time.Duration.between(now, actualEndTime).getSeconds();
            return ApiResponse.success("获取剩余时间成功", Math.max(0, remainingSeconds)); // 确保不返回负数

        } catch (Exception e) {
            log.error("获取考试剩余时间失败", e);
            return ApiResponse.error("获取考试剩余时间失败: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<?> getStudentExamRecordDetail(Long examId, Long studentId) {
        ExamRecord record = examRecordMapper.selectOne(
            new QueryWrapper<ExamRecord>()
                .eq("exam_id", examId)
                .eq("student_id", studentId)
        );
        
        if (record == null) {
            return ApiResponse.error("未找到考试记录");
        }

        // 构建详细的响应数据
        Map<String, Object> detailedRecord = new HashMap<>();
        detailedRecord.put("examRecord", record); // 包含基本记录信息

        // 加载考试题目详情
        try {
            List<ExamQuestion> examQuestions = examQuestionMapper.selectList(
                new QueryWrapper<ExamQuestion>().eq("exam_id", examId).orderByAsc("`order`")
            );
            List<Map<String, Object>> questions = new ArrayList<>();
            Map<Long, Question> questionMap = new HashMap<>(); // 用于后续评分详情处理
            
            for (ExamQuestion eq : examQuestions) {
                Question question = questionMapper.selectById(eq.getQuestionId());
                if (question != null) {
                    questionMap.put(question.getId(), question); // 存储完整Question对象
                    
                    Map<String, Object> questionInfo = new HashMap<>();
                    questionInfo.put("id", question.getId());
                    questionInfo.put("content", question.getContent());
                    questionInfo.put("type", question.getType());
                    questionInfo.put("options", question.getOptions());
                    // 返回正确答案
                    questionInfo.put("answers", question.getAnswers()); 
                    questionInfo.put("explanation", question.getExplanation());
                    questionInfo.put("knowledgePoint", question.getKnowledgePoint());
                    questionInfo.put("score", eq.getScore()); // 使用 exam_questions 表中的分数
                    questionInfo.put("order", eq.getOrder());
                    questions.add(questionInfo);
                }
            }
            detailedRecord.put("questions", questions); // 将题目列表添加到响应中

            // 如果考试已批改完成，添加详细的评分信息
            if ("MARKED".equals(record.getStatus())) {
                // 解析评分详情，并可能补充题目信息（如果需要）
                if (record.getScoringDetails() != null) {
                    Map<String, Object> scoringDetails = objectMapper.readValue(record.getScoringDetails(), Map.class);
                    // 可以在这里进一步处理 scoringDetails，比如结合 questionMap 添加更多题目信息
                    detailedRecord.put("scoringDetails", scoringDetails);
                }

                // 获取考试基本信息
                Exam exam = examMapper.selectById(examId);
                if (exam != null) {
                    Map<String, Object> examInfo = new HashMap<>();
                    examInfo.put("title", exam.getTitle());
                    examInfo.put("totalScore", exam.getTotalScore());
                    examInfo.put("passScore", exam.getPassScore());
                    detailedRecord.put("examInfo", examInfo);
                }
            }
        } catch (Exception e) {
            log.error("获取考试记录详情时出错 (ExamID: {}, StudentID: {}): {}", examId, studentId, e.getMessage(), e);
            // 根据需要决定是否因为题目或评分详情加载失败而返回错误
            // return ApiResponse.error("获取考试记录详情失败: " + e.getMessage());
        }

        return ApiResponse.success("获取考试记录成功", detailedRecord);
    }

    @Override
    public ApiResponse<?> getStudentExamRecordList(Long studentId) {
        try {
            // 获取学生的所有考试记录，但只包含已批改的记录
            QueryWrapper<ExamRecord> wrapper = new QueryWrapper<>();
            wrapper.eq("student_id", studentId)
                   .eq("status", "MARKED") // 新增：只查询状态为 MARKED 的记录
                   .orderByDesc("create_time"); 
            List<ExamRecord> records = examRecordMapper.selectList(wrapper);
            
            // --- 后续的统计和格式化逻辑基于过滤后的 records 进行 ---
            int totalMarkedExams = records.size(); // 现在是已批改的考试总数
            int passedExams = 0;
            double totalScore = 0;
            
            List<Map<String, Object>> formattedRecords = new ArrayList<>();
            
            for (ExamRecord record : records) {
                // 构建每条记录的详细信息 (只处理 MARKED 记录)
                Map<String, Object> recordDetail = new HashMap<>();
                recordDetail.put("id", record.getId());
                recordDetail.put("examId", record.getExamId());
                recordDetail.put("status", record.getStatus()); // 肯定是 MARKED
                recordDetail.put("score", record.getScore());
                recordDetail.put("submitTime", record.getSubmitTime());
                recordDetail.put("passed", record.getPassed());
                
                // 获取考试信息
                Exam exam = examMapper.selectById(record.getExamId());
                if (exam != null) {
                    recordDetail.put("examTitle", exam.getTitle());
                    recordDetail.put("totalScore", exam.getTotalScore());
                    recordDetail.put("passScore", exam.getPassScore());
                }
                
                // 统计通过的考试 (因为已经是 MARKED, 直接统计)
                if (record.getScore() != null) {
                    totalScore += record.getScore();
                    if (Boolean.TRUE.equals(record.getPassed())) {
                        passedExams++;
                    }
                }
                
                formattedRecords.add(recordDetail);
            }
            
            // 构建响应数据 (统计信息现在基于已批改记录)
            Map<String, Object> response = new HashMap<>();
            response.put("studentId", studentId);
            // 注意：这里的统计信息现在反映的是已批改的考试情况
            response.put("totalMarkedExams", totalMarkedExams); 
            response.put("passedExams", passedExams);
            response.put("averageScore", totalMarkedExams > 0 ? totalScore / totalMarkedExams : 0);
            response.put("passRate", totalMarkedExams > 0 ? (double) passedExams / totalMarkedExams : 0);
            response.put("examRecords", formattedRecords); // 只包含 MARKED 的记录列表
            
            log.info("Successfully retrieved MARKED exam records for student {}: {} records found", studentId, totalMarkedExams);
            return ApiResponse.success("获取已批改考试记录列表成功", response);
            
        } catch (Exception e) {
            log.error("Error getting MARKED exam records for student {}: {}", studentId, e.getMessage(), e);
            return ApiResponse.error("获取已批改考试记录列表失败: " + e.getMessage());
        }
    }
} 